﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.Mvc;
using System.Web.Mvc.Html;
using System.Globalization;
using System.Linq.Expressions;

namespace Tencent.OA.ACM.App
{
    public static class LiteralExtensions
    {
        public static MvcHtmlString StrictText(this HtmlHelper html, string text)
        {
            string str = text;
            if (!string.IsNullOrEmpty(str))
            {
                str = ReplaceBreak(str);
                return MvcHtmlString.Create(str);
            }
            else
            {
                return MvcHtmlString.Create("--");
            }
        }

        public static MvcHtmlString StrictText<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression)
        {
            object modelValue = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData).Model;
            return TextHelper(htmlHelper, ExpressionHelper.GetExpressionText(expression), modelValue, modelValue == null, str =>ReplaceBreak(str));
        }

        static string ReplaceBreak(string value)
        {
            string str = value;
            if (!string.IsNullOrEmpty(str))
            {
                str = str.Replace("\r\n", "<br />");
            }
            return str;
        }
        public static MvcHtmlString Literal(this HtmlHelper html, object text)
        {
            string name = Convert.ToString(text, CultureInfo.CurrentCulture);
            return LiteralHelper(html, name, text, (text == null)/* useViewData */);
        }

        public static MvcHtmlString LiteralFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression)
        {
            object modelValue = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData).Model;
            return LiteralHelper(htmlHelper, ExpressionHelper.GetExpressionText(expression), modelValue, modelValue == null);
        }

        internal static MvcHtmlString LiteralHelper(HtmlHelper htmlHelper, string name, object value, bool useViewData)
        {
            return TextHelper(htmlHelper, name, value, useViewData, null);
        }

        internal static MvcHtmlString TextHelper(HtmlHelper htmlHelper, string name, object value, bool useViewData, Func<string, string> replacer)
        {
            name = htmlHelper.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(name);
            if (String.IsNullOrEmpty(name))
            {
                throw new ArgumentNullException("name");
            }

            CultureInfo currentCulture = CultureInfo.CurrentCulture;
            string valueParameter = Convert.ToString(value, currentCulture);
            string attemptedValue = (string)GetModelStateValue(htmlHelper, name, typeof(string), currentCulture);
            string literalText = attemptedValue ?? (useViewData ? Convert.ToString(htmlHelper.ViewData.Eval(name), currentCulture) : valueParameter);
            if (String.IsNullOrEmpty(literalText))
            {
                return MvcHtmlString.Create("--");
            }
            if (replacer != null)
                literalText = replacer(literalText);
            return MvcHtmlString.Create(literalText);
        }

        static object GetModelStateValue(HtmlHelper htmlHelper, string key, Type destinationType, CultureInfo culture)
        {
            ModelState modelState;
            if (htmlHelper.ViewData.ModelState.TryGetValue(key, out modelState))
            {
                if (modelState.Value != null)
                {
                    return modelState.Value.ConvertTo(destinationType, culture);
                }
            }
            return null;
        }
    }
}
